package db

import (
	"github.com/google/uuid"
	"gomonitor-server/src/domain"
	"gomonitor-server/src/dto"
	"gomonitor-server/src/mylog"
	"strings"
	"time"
)

func GetHostStateByIpAndHostname(ip string, hostname string, dbTool *DbTool) (string, error) {
	var hostStates []domain.HostState
	dbTool.db.Model(&domain.HostState{}).Where("ip = ? AND hostname = ?", ip, hostname).Find(&hostStates)
	if len(hostStates) == 0 {
		return "", nil
	} else {
		mylog.Logger.Debugf("主机(ip:%s,host:%s)状态存在记录:%s", ip, hostname, hostStates[0].ID)
		return hostStates[0].ID, nil
	}
}

func FindHostStateByIp(ipList *[]string, dbTool *DbTool) ([]domain.HostState, error) {
	var hostStates []domain.HostState
	// 解引用指针以获取切片
	slice := *ipList
	// 将切片转换为逗号分隔的字符串
	ipsStr := strings.Join(slice, ",")
	dbTool.db.Model(&domain.HostState{}).Where("ip in (?)", ipsStr).Find(&hostStates)
	return hostStates, nil
}

func UpdateErrorHostState() {
	dbTool, err := GetConnection()
	if err != nil {
		// 处理错误
		mylog.Logger.Error("连接MySQL失败", err)
		return
	}
	err = dbTool.db.Model(&domain.HostState{}).Where("last_disconnect_time IS NULL").Update("last_disconnect_time", time.Now()).Error
	if err != nil {
		// 处理错误
		mylog.Logger.Error("更新主机状态错误数据失败", err)
		return
	}
}
func HostStateOnline(connectionInfo *dto.ConnectionInfo) {
	dbTool, err := GetConnection()
	if err != nil {
		// 处理错误
		mylog.Logger.Error(" 更新主机状态,连接MySQL失败", err)
		return
	}
	sysInfo := connectionInfo.LastSysInfo
	if sysInfo != nil {
		var ip string
		if len(sysInfo.NetInfo) > 0 {
			ip = sysInfo.NetInfo[0].Ip
		} else {
			ip = ""
		}

		id, err := GetHostStateByIpAndHostname(ip, sysInfo.Hostname, dbTool)
		if err != nil {
			// 处理错误
			mylog.Logger.Errorf("查询主机%s状态失败%s", ip, err.Error())
			return
		}
		mylog.Logger.Debugf("主机(ip:%s,hostname:%s)状态id:%s", sysInfo.Hostname, ip, id)
		var hostState domain.HostState
		if id == "" {
			hostState = domain.HostState{
				ID:              uuid.New().String(),
				IP:              ip,
				Hostname:        sysInfo.Hostname,
				HostState:       1,
				LastConnectTime: connectionInfo.StartTime,
			}
			result := dbTool.db.Create(&hostState)
			if result.Error != nil {
				// 处理错误
				mylog.Logger.Errorf("插入主机(ip:%s,hostname:%s)状态失败:%s", sysInfo.Hostname, ip, err)
				return
			}
		} else {
			hostState = domain.HostState{
				ID:              id,
				HostState:       1,
				LastConnectTime: connectionInfo.StartTime,
			}
			dbTool.db.Model(&domain.HostState{}).Where("id=?", id).Updates(hostState)
		}
		hostOnlineLog(connectionInfo)
		mylog.Logger.Infof("主机(ip:%s, hostname:%s)上线成功", ip, sysInfo.Hostname)
	}
}

func HostStateOffline(connectionInfo *dto.ConnectionInfo) {
	dbTool, err := GetConnection()
	if err != nil {
		// 处理错误
		mylog.Logger.Error("连接MySQL失败", err)
		return
	}
	sysInfo := connectionInfo.LastSysInfo
	if sysInfo != nil {
		var ip string
		if len(sysInfo.NetInfo) > 0 {
			ip = sysInfo.NetInfo[0].Ip
		} else {
			ip = ""
		}

		id, err := GetHostStateByIpAndHostname(ip, sysInfo.Hostname, dbTool)
		if err != nil {
			// 处理错误
			mylog.Logger.Error("查询主机状态失败", err)
			return
		}
		result := dbTool.db.Model(&domain.HostState{}).Where("id=?", id).Updates(domain.HostState{HostState: 0, LastConnectTime: connectionInfo.EndTime})

		if result.Error != nil {
			// 处理错误
			mylog.Logger.Error("更新主机状态失败", result.Error)
			return
		}
		rowsAffected := result.RowsAffected
		if rowsAffected > 0 {
			// 更新成功
			mylog.Logger.Info("成功更新主机状态，受影响的行数:", rowsAffected)
		} else {
			// 没有进行更新
			mylog.Logger.Info("未更新主机状态")
		}

		hostOfflineLog(connectionInfo)
		mylog.Logger.Infof("主机(ip:%s, hostname:%s)离线成功", ip, sysInfo.Hostname)
	}
}

func deleteHost(ip string, dbTool *DbTool) error {

	// 根据ip查询HostState表
	var hostState domain.HostState
	result := dbTool.db.Model(&domain.HostState{}).Where("ip = ?", ip).First(&hostState)
	if result.Error != nil {
		if result.RowsAffected == 0 {
			return nil
		} else {
			return result.Error
		}
	}

	// 根据hostStateId删除HostHostTag关系表
	mylog.Logger.Info("删除ip:", ip, "的HostHostTag关系表")
	dbTool.db.Model(&domain.HostHostTag{}).Where("host_state_id = ?", hostState.ID).Delete(&domain.HostHostTag{})

	// 根据ip删除HostLast表
	mylog.Logger.Info("删除ip:", ip, "的HostLast")
	// Assuming HostLast is a domain model, replace it with the actual model if it's different
	dbTool.db.Model(&domain.HostLast{}).Where("net1_ip = ? or net2_ip = ?", ip, ip).Delete(&domain.HostLast{})

	// 根据ip删除Host表
	mylog.Logger.Info("删除ip:", ip, "的Host")
	// Assuming Host is a domain model, replace it with the actual model if it's different
	dbTool.db.Model(&domain.Host{}).Where("net1_ip = ? or net2_ip = ?", ip, ip).Delete(&domain.Host{})

	// 根据ip删除HostStateLog表
	mylog.Logger.Info("删除ip:", ip, "的HostStateLog")
	// Assuming HostStateLog is a domain model, replace it with the actual model if it's different
	dbTool.db.Model(&domain.HostStateLog{}).Where("ip = ?", ip).Delete(&domain.HostStateLog{})

	// 根据ip删除HostState表
	mylog.Logger.Info("删除ip:", ip, "的HostState")
	dbTool.db.Model(&domain.HostState{}).Where("ip = ?", ip).Delete(&domain.HostState{})

	return nil
}
func HostDelete(ipList []string) error {
	dbTool, err := GetConnection()
	if err != nil {
		return err
	} else {
		for _, ip := range ipList {
			mylog.Logger.Info("删除主机:", ip)
			err = deleteHost(ip, dbTool)
			if err != nil {
				return err
			}
		}
	}
	return nil
}
